/* eslint-disable eol-last */
import { Agent } from "egg";
// import { uuid } from "@mac-xiang/method";
// const sign = uuid;

import { getCache, setCache, delCache, oa, Cache, LOG, HistoryS } from "./itf";

const wl = new LOG();
const cache: Cache = { _tmkTimeData: {} };
function cleanTime() {
  const a = cache._tmkTimeData, t = new Date().getTime();
  Object.keys(a).forEach(k => {
    const d = a[k];
    if (d.time && !(d.time > t)) {
      const dh = d.history;
      if (dh) {
        Object.keys(dh).forEach(hk => { // 将日志写入文件
          wl.write(hk, dh[hk]);
        });
      }
      delete a[k];
    }
  });
}
setInterval(() => {
  try {
    cleanTime();
  } catch (error) {
    console.log("写日志发生严重错误", error);
  }
}, 60000);

function getCachePath(d: string[]) {
  if (Array.isArray(d) && d.length > 0) {
    let t: oa = cache, i: string | undefined;
    while (d.length > 1) {
      i = d.shift();
      if (i) {
        if (!t[i]) t[i] = {};
        t = t[i];
      }
    }
    return t;
  }
}
//#region setTmkTimeData 无用折叠
/* function setTmkTimeData(d: setCache): boolean {
  const path = d.path, value = d.value;
  if (path[0] == "_tmkTimeData") {
    if (path[2] == "time" && cache._tmkTimeData[path[1]]) { // 上/离 线
      const rooms: string[] = [];
      rooms.push(path[1]);
      cache._tmkTimeData[path[1]].rooms.forEach(a => {
        rooms.push(a);
      });
      const time = new Date().getTime();
      let v = value as number;
      if (value && !(value > time)) v = time + 60000;
      cache._tmkTimeData[path[1]].time = v;

      const uid = rooms.shift() as string;
      const msg = {
        time: new Date().getTime(),
        type: "con",
        source: uid,
        content: value ? "离开会话" : "进入会话"
      };
      const uh = cache._tmkTimeData[uid].history;
      if (uh) { // 普通用户
        Object.keys(uh).forEach(con => { uh[con].push(msg); });
      } else { // 管理员
        Object.keys(cache._tmkTimeData).forEach(id => {
          const h = cache._tmkTimeData[id].history;
          if (h) {
            Object.keys(h).forEach(con => {
              if (h[con]) h[con].push(msg);
            });
          }
        });
      }
      return true;
    } else if (path.length == 4 && value && d.push) {
      if (path[2] == "history" && value.content == "创建会话") {
        if (!cache._tmkTimeData[path[1]]) {
          cache._tmkTimeData[path[1]] = {
            time: 0,
            rooms: Array.isArray(value.rooms) ? value.rooms : [path[3]],
          };
        }
        let th = cache._tmkTimeData[path[1]].history;
        if (!th) {
          th = {};
          cache._tmkTimeData[path[1]].history = th;
        }
        th[path[3]] = [value];
      }
    } else if (path.length == 3 &&
      cache._tmkTimeData[path[1]] &&
      path[0] == "_tmkTimeData" &&
      path[2] == "rooms" &&
      value &&
      (value.type == "join" || value.type == "leave") &&
      d.push) {
      const uh = cache._tmkTimeData[path[1]];
      const room = value.content as string;
      let rooms = uh.rooms;
      if (!Array.isArray(rooms)) {
        rooms = [];
        uh.rooms = rooms;
      }
      if (rooms.indexOf(room) < 0) {
        rooms.push(room);
      }
      if (uh.history) {
        let r = false;
        if (uh.history[room]) {
          uh.history[room].push(value);
          r = true;
        } else {
          const is = Object.keys(cache._tmkTimeData);
          for (let i = 0; i < is.length; i++) {
            const h = cache._tmkTimeData[is[i]].history;
            if (h) {
              const rs = Object.keys(h);
              for (let j = 0; j < rs.length; j++) {
                if (rs[j] == room) {
                  h[rs[j]].push(value);
                  r = true;
                }
              }
            }
            if (r) return r;
          }
        }
      }
    }
  }
  return false;
} */
//#endregion
export default (agent: Agent) => {

  // agent.messenger.on("egg-ready", () => { // 通知缓存进程,取信号
  //   agent.messenger.sendToApp("_tmkSetCacheSign", sign);
  // });

  agent.messenger.on("_tmkGetCache", async (d: getCache) => {
    let ret: oa | undefined = {};
    if ((d.method & 2) && d.path[0] == "_tmkTimeData") {
      const room = d.path[1];
      let tr = "";
      const ids = Object.keys(cache._tmkTimeData);
      for (let idi = 0; idi < ids.length; idi++) {
        const history = cache._tmkTimeData[ids[idi]].history as HistoryS;
        const rs = Object.keys(history);
        let rsi = 0;
        while (rsi < rs.length) {
          if (rs[rsi] == room) {
            tr = ids[idi];
            break;
          }
          rsi++;
        }
        if (rsi < rs.length) break;
      }

      ret[d.path[0]] = tr;
    } else {
      ret = getCachePath(d.path);
    }
    agent.messenger.sendTo(d.pid, d.sign, ret ? ret[d.path[0]] : undefined);
    if (ret && (d.method & 1) && d.path[0] != "_tmkTimeData") {
      delete ret[d.path[0]];
    }
  });
  agent.messenger.on("_tmkSetCache", async (d: setCache) => {
    // console.log("d=", d);
    // console.log("cache=", cache._tmkTimeData);
    let r = false;
    const t = getCachePath(d.path);
    if (t) {
      if (d.push) {
        if (!t[d.path[0]]) t[d.path[0]] = [];
        if (Array.isArray(t[d.path[0]])) {
          t[d.path[0]].push(d.value);
        } else {
          t[d.path[0]][Object.keys(t[d.path[0]]).length] = d.value;
        }
      } else {
        t[d.path[0]] = d.value;
      }
      r = true;
    }
    agent.messenger.sendTo(d.pid, d.sign, r);
  });
  agent.messenger.on("_tmkDelCache", (d: delCache) => {
    let r: any;
    if (Array.isArray(d.path) && d.path.length > 0) {
      const t = getCachePath(d.path);
      if (t) {
        if (d.path[0] != "_tmkTimeData") {
          if (d.pop) {
            if (Array.isArray(t[d.path[0]])) r = t[d.path[0]].pop();
            else {
              const k = Object.keys(t[d.path[0]]);
              if (k.length) {
                r = t[d.path[0]][k[k.length - 1]];
                delete t[d.path[0]][k[k.length - 1]];
              }
            }
          } else {
            r = t[d.path[0]];
            delete t[d.path[0]];
          }
        }
      }
    }
    agent.messenger.sendTo(d.pid, d.sign, r);
  });
};